By Dimitre Novatchev |
Language | XPath |
Category | designpatterns, namespace, msxml |
Posted | 22 Mar 2001 |
Updated | 22 Mar 2001 |
Summary | ||||||||||||
Presented is a common technique to determine whether the type of a node is attribute or a namespace. | ||||||||||||
Whenever you have to perform a more general processing of an xml document, whose type is not known in advance (e.g. as in an XSL Debugger or in a XPath visualisation tool), you need to be able to determine the concrete type of a (any) node. | ||||||||||||
While for node types for which a node-test exists this is straightforward e.g: | ||||||||||||
|
||||||||||||
There isn't any straightforward way to determine if the current node is an attribute or a namespace. | ||||||||||||
This is because in XPath there isn't a node-test for attribute or namespace nodes. | ||||||||||||
If we try the following: | ||||||||||||
self::attribute | ||||||||||||
we are asking whether the current node is ***an element*** with name "attribute". | ||||||||||||
It is not possible to specify | ||||||||||||
self::attribute::* | ||||||||||||
because what follows the self:: axis name must be a test -- not another axis. | ||||||||||||
The same problem exists for trying to determine if a node is a namespace node. | ||||||||||||
Here is one solution to the attribute/namespace node-type identification problem: | ||||||||||||
We can use a set equasion to determine whether or not the current node is a member of the set of all attributes of its parent. | ||||||||||||
The set of all attributes of the parent of a node nd is: | ||||||||||||
(1) ../@* | ||||||||||||
The current node is: | ||||||||||||
(2) . | ||||||||||||
We can test if a node nd belongs to a node-set ns like this: | ||||||||||||
(3) count(nd | ns) = count(ns) | ||||||||||||
Substituting (1) and (2) in (3) we obtain: | ||||||||||||
count(. | ../@*) = count(../@*) | ||||||||||||
In the same way to test for a namespace we can use the following expression: | ||||||||||||
count(. | ../namespace::*) = count(../namespace::*) | ||||||||||||
I'm going to show how to use these two tests in my next snippet. | ||||||||||||
Code | ||||||||||||